Application developers have traditionally faced a number of challenges in horizontally scaling applications to multiple servers. Scaling is particularly useful to World Wide Web application developers who may, for example, require geographically distributed application servers to provide users with better performance. In one example, suppose a user of a web-based application logs on to a web site to change information in an existing user account. Typically, in a distributed application, one application server is selected to handle the transaction based on its geographical location, availability or other factors. The selected server accesses the account data and makes the requested changes locally and the updated data must then be shared with the other servers so that the user's future interactions with any of the servers will reflect the updates. Additionally, the fact that some servers may go offline while others come online must be considered.
This scaling challenge is faced by developers in many development environments, including developers using the popular Java development platform. The Java platform's goal in providing a platform independent environment is generally met by the fact that Java source code is compiled into an intermediate language called “bytecode,” which can reside on any hardware platform. In order to run the bytecode, it must be compiled into machine code via a Java Virtual Machine (JVM). A JVM is a platform-independent execution environment that converts Java byte code into machine language and executes it. The JVM provides the developer with the tools necessary for multi-threaded applications, including thread support, synchronization and garbage collection.
FIG. 1A illustrates a traditional implementation of a Java application running on a virtual machine under a given operating system on a processing system or server. As developers have attempted to scale Java applications to multiple processing systems, difficulties in maintaining object and primitive states across the systems become more numerous.
Traditionally, application developers themselves have been required to account for scaling using common forms of inter-server communication in order to share objects amongst distributed JVMs. One form of communication is Remote Method Invocation (RMI), which is a set of protocols that enables Java objects to communicate remotely with other Java objects. Another form of communication is the Java Message Service (JMS), which is an Application Program Interface (API) for accessing enterprise messaging systems. JMS supports both message queuing and publish-subscribe styles of messaging. Java Temporary Caching (JCache) is a distributed caching system for server-side Java applications.
While each of these techniques allow the developer the flexibility to add scaling to their application, the conventional techniques require application code to be modified, resulting in significant added complexity and development costs. Further, the conventional techniques limit scalability of the application tier, are often quite slow, and tend to abuse database infrastructure for transient needs. Finally, the task of maintaining object identity is a challenge as multiple copies of the same object can be created at the different application servers.
An improved technology is needed for maintaining consistent data across virtual machines.